"""
优先级管理API端点
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, Response
from motor.motor_asyncio import AsyncIOMotorDatabase

from app.core.database import get_database
from app.core.response import success_response, error_response, ErrorTypes, ApiResponse
from app.api.deps import get_current_user
from app.models.user import User
from app.models.priority import PriorityCreate, PriorityUpdate, PriorityResponse, ModuleType
from app.services.priority_service import priority_service, PriorityNotModifiedError

router = APIRouter()

@router.get("/", response_model=ApiResponse, summary="获取优先级列表")
async def get_priorities(
    module_type: Optional[str] = Query(None, description="模块类型"),
    include_disabled: bool = Query(False, description="是否包含已禁用的优先级"),
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """获取优先级列表"""
    try:
        query = {}
        if module_type:
            if module_type not in [m.value for m in ModuleType]:
                raise HTTPException(status_code=400, detail=f"无效的模块类型: {module_type}")
            query["module_type"] = module_type
        
        # 默认只返回启用的优先级
        if not include_disabled:
            query["is_enabled"] = True

        cursor = db.priorities.find(query).sort("sort_order", 1)
        priorities = await cursor.to_list(length=None)
        
        # 将ObjectId转换为字符串
        for p in priorities:
            p["_id"] = str(p["_id"])
            
        return success_response(data=priorities)

    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"获取优先级列表失败: {str(e)}"
        )

@router.get("/all/options", response_model=ApiResponse, summary="获取所有模块的优先级选项")
async def get_all_priority_options(
    force_refresh: bool = Query(False, description="是否强制刷新缓存"),
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """获取所有模块的优先级选项"""
    try:
        options = await priority_service.get_all_priority_options(db, force_refresh)
        return success_response(data=options)
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"获取所有模块的优先级选项失败: {str(e)}"
        )

@router.get("/{priority_id}", response_model=ApiResponse, summary="获取优先级详情")
async def get_priority(
    priority_id: str,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """获取优先级详情"""
    try:
        from bson import ObjectId
        
        # 验证ID格式
        if not ObjectId.is_valid(priority_id):
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message="无效的优先级ID格式"
            )
        
        # 查询优先级
        priority = await db.priorities.find_one({"_id": ObjectId(priority_id)})
        
        if not priority:
            return error_response(
                error_type=ErrorTypes.NOT_FOUND,
                message="未找到指定的优先级"
            )
        
        # 转换为响应格式
        priority_response = PriorityResponse(
            id=str(priority["_id"]),
            name=priority["name"],
            code=priority["code"],
            module_type=priority["module_type"],
            description=priority.get("description"),
            color=priority.get("color", "#1890ff"),
            sort_order=priority.get("sort_order", 0),
            is_enabled=priority.get("is_enabled", True),
            created_at=priority.get("created_at"),
            updated_at=priority.get("updated_at")
        )
        
        return success_response(
            data=priority_response,
            message="获取优先级详情成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"获取优先级详情失败: {str(e)}"
        )

@router.post("/", response_model=ApiResponse, summary="创建优先级")
async def create_priority(
    priority: PriorityCreate,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """创建优先级"""
    try:
        from datetime import datetime
        from bson import ObjectId
        
        # 验证模块类型
        if priority.module_type not in [m.value for m in ModuleType]:
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message=f"无效的模块类型: {priority.module_type}"
            )
        
        # 检查代码是否已存在
        existing = await db.priorities.find_one({
            "module_type": priority.module_type,
            "code": priority.code
        })
        
        if existing:
            return error_response(
                error_type=ErrorTypes.ALREADY_EXISTS,
                message=f"优先级代码 '{priority.code}' 在 {priority.module_type} 模块中已存在"
            )
        
        # 准备数据
        now = datetime.utcnow()
        priority_data = {
            "name": priority.name,
            "code": priority.code,
            "module_type": priority.module_type,
            "description": priority.description,
            "color": priority.color or "#1890ff",
            "sort_order": priority.sort_order or 0,
            "is_enabled": priority.is_enabled if priority.is_enabled is not None else True,
            "created_at": now,
            "updated_at": now
        }
        
        # 插入数据
        result = await db.priorities.insert_one(priority_data)
        
        # 获取创建的优先级
        created_priority = await db.priorities.find_one({"_id": result.inserted_id})
        
        # 转换为响应格式
        priority_response = PriorityResponse(
            id=str(created_priority["_id"]),
            name=created_priority["name"],
            code=created_priority["code"],
            module_type=created_priority["module_type"],
            description=created_priority.get("description"),
            color=created_priority.get("color", "#1890ff"),
            sort_order=created_priority.get("sort_order", 0),
            is_enabled=created_priority.get("is_enabled", True),
            created_at=created_priority.get("created_at"),
            updated_at=created_priority.get("updated_at")
        )
        
        # 刷新缓存
        await priority_service.invalidate_cache(priority.module_type)
        
        return success_response(
            data=priority_response,
            message="创建优先级成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"创建优先级失败: {str(e)}"
        )

@router.put("/{priority_id}", response_model=ApiResponse, summary="更新优先级")
async def update_priority(
    priority_id: str,
    priority: PriorityUpdate,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """更新优先级"""
    try:
        from datetime import datetime
        from bson import ObjectId
        
        # 验证ID格式
        if not ObjectId.is_valid(priority_id):
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message="无效的优先级ID格式"
            )
        
        # 查询优先级
        existing = await db.priorities.find_one({"_id": ObjectId(priority_id)})
        
        if not existing:
            return error_response(
                error_type=ErrorTypes.NOT_FOUND,
                message="未找到指定的优先级"
            )
        
        # 如果更新代码，检查是否与其他优先级冲突
        if priority.code and priority.code != existing["code"]:
            code_conflict = await db.priorities.find_one({
                "_id": {"$ne": ObjectId(priority_id)},
                "module_type": existing["module_type"],
                "code": priority.code
            })
            
            if code_conflict:
                return error_response(
                    error_type=ErrorTypes.ALREADY_EXISTS,
                    message=f"优先级代码 '{priority.code}' 在 {existing['module_type']} 模块中已存在"
                )
        
        # 准备更新数据
        update_data = {}
        if priority.name is not None:
            update_data["name"] = priority.name
        if priority.code is not None:
            update_data["code"] = priority.code
        if priority.description is not None:
            update_data["description"] = priority.description
        if priority.color is not None:
            update_data["color"] = priority.color
        if priority.sort_order is not None:
            update_data["sort_order"] = priority.sort_order
        if priority.is_enabled is not None:
            update_data["is_enabled"] = priority.is_enabled
        
        update_data["updated_at"] = datetime.utcnow()
        
        # 更新数据
        await db.priorities.update_one(
            {"_id": ObjectId(priority_id)},
            {"$set": update_data}
        )
        
        # 获取更新后的优先级
        updated_priority = await db.priorities.find_one({"_id": ObjectId(priority_id)})
        
        # 转换为响应格式
        priority_response = PriorityResponse(
            id=str(updated_priority["_id"]),
            name=updated_priority["name"],
            code=updated_priority["code"],
            module_type=updated_priority["module_type"],
            description=updated_priority.get("description"),
            color=updated_priority.get("color", "#1890ff"),
            sort_order=updated_priority.get("sort_order", 0),
            is_enabled=updated_priority.get("is_enabled", True),
            created_at=updated_priority.get("created_at"),
            updated_at=updated_priority.get("updated_at")
        )
        
        # 刷新缓存
        await priority_service.refresh_cache(updated_priority["module_type"])
        
        return success_response(
            data=priority_response,
            message="更新优先级成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"更新优先级失败: {str(e)}"
        )

@router.delete("/{priority_id}", response_model=ApiResponse, summary="删除优先级")
async def delete_priority(
    priority_id: str,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """删除优先级"""
    try:
        from bson import ObjectId
        
        # 验证ID格式
        if not ObjectId.is_valid(priority_id):
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message="无效的优先级ID格式"
            )
        
        # 查询优先级
        priority = await db.priorities.find_one({"_id": ObjectId(priority_id)})
        
        if not priority:
            return error_response(
                error_type=ErrorTypes.NOT_FOUND,
                message="未找到指定的优先级"
            )
        
        # 删除优先级
        await db.priorities.delete_one({"_id": ObjectId(priority_id)})
        
        # 刷新缓存
        await priority_service.invalidate_cache(priority["module_type"])
        
        return success_response(
            data={"id": priority_id},
            message="删除优先级成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"删除优先级失败: {str(e)}"
        )

@router.post("/cache/refresh", response_model=ApiResponse, summary="刷新优先级缓存")
async def refresh_priority_cache(
    module_type: Optional[str] = Query(None, description="模块类型，不传则刷新所有模块"),
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """刷新优先级缓存"""
    try:
        if module_type:
            # 验证模块类型
            if module_type not in [m.value for m in ModuleType]:
                return error_response(
                    error_type=ErrorTypes.VALIDATION_ERROR,
                    message=f"无效的模块类型: {module_type}"
                )
            
            # 刷新指定模块的缓存
            result = await priority_service.refresh_cache(module_type)
            
            module_name_map = {
                "task": "任务",
                "project": "项目",
                "defect": "缺陷",
                "requirement": "需求",
                "test_case": "测试用例"
            }
            module_name = module_name_map.get(module_type, module_type)
            
            if result["refreshed_count"] > 0:
                message = f"刷新“{module_name}”模块优先级缓存成功"
            else:
                message = f"“{module_name}”模块没有需要刷新的缓存"
        else:
            # 刷新所有缓存
            result = await priority_service.refresh_cache()
            refreshed_count = result["refreshed_count"]
            refreshed_modules = result["refreshed_modules"]
            
            if refreshed_count > 0:
                module_names = [m.replace("_", "") for m in refreshed_modules]
                message = f"刷新所有优先级缓存成功，共刷新 {refreshed_count} 个模块: {', '.join(module_names)}"
            else:
                message = "没有需要刷新的缓存"
        
        return success_response(
            data=result,
            message=message
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"刷新优先级缓存失败: {str(e)}"
        )

@router.post("/initialize", response_model=ApiResponse, summary="初始化默认优先级")
async def initialize_priorities(
    module_type: str = Query(..., description="要初始化的模块类型"),
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """初始化指定模块的默认优先级"""
    try:
        created_count = await priority_service.initialize_default_priorities(db, module_type)
        return success_response(
            data={"created_count": created_count},
            message=f"为模块 {module_type} 初始化了 {created_count} 个默认优先级"
        )
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"初始化默认优先级失败: {str(e)}"
        )